package perform.database;

import java.lang.reflect.Field;

import perform.constants.Cascade;
import perform.constants.Index;
import perform.mappings.ClassMappings;
import perform.type.Type;

public abstract class ForeignKeyProcessor implements ColumnProcessor {
	
	protected Field field;
	protected ColumnProcessor idColumn;
	protected Class<? extends Type> target;
	protected Cascade cascade;
	
	protected String name;
	
	protected String columnDefinition;
	protected String indexDefinition;
	protected String foreignKeyDefinition;
	
	protected ForeignKeyProcessor(Field field, String name){
		this.field = field;
		this.name = name;
	}

	protected void buildColumnDefinition(){
		StringBuilder builder = new StringBuilder("\t`").append(name).append("` ");
		builder.append(getType());
		if(getLength() > 0 && getPrecision() > 0){
			builder.append("(").append(getLength()).append(",").append(getPrecision()).append(")");
		} else if(getLength() > 0){
			builder.append("(").append(getLength()).append(")");
		}
		if(!isNullable()){
			builder.append(" not null");
		}
		builder.append(" ,\n");
		columnDefinition = builder.toString();
	}
	protected void buildForeignDefinition(){
		StringBuilder builder = new StringBuilder("\tadd constraint `");
		builder.append(name).append("_fk` foreign key ( `").append(name).append("` ) references `");
		builder.append(ClassMappings.getTable(target)).append("` ( `").append(idColumn.getName()).append("` ) ");
		switch (cascade) {
		case CASCADE:
			builder.append("on update cascade on delete cascade ,\n");
			break;
		case RESTRICT:
			builder.append("on update restrict on delete restrict ,\n");
			break;
		case SET_DEFAULT:
			builder.append("on update cascade on delete set default ,\n");
			break;
		case SET_NULL:
			builder.append("on update cascade on delete set null ,\n");
			break;
		default:
			builder.append(",\n");
			break;
		}
		foreignKeyDefinition = builder.toString();
	}
	protected void buildIndexDefinition(){
		indexDefinition = new StringBuilder("\tunique ( `").append(name).append("` ) ,\n").toString();
	}

	@Override
	public Field getField() {
		return field;
	}
	@Override
	public String getName() {
		return name;
	}
	@Override
	public String getType() {
		return idColumn.getType();
	}
	@Override
	public int getLength() {
		return idColumn.getLength();
	}
	@Override
	public int getPrecision() {
		return idColumn.getPrecision();
	}
	@Override
	public String[] getValues() {
		return null;
	}
	@Override
	public String getDefaultValue() {
		return null;
	}
	@Override
	public boolean hasConstraints() {
		return true;
	}
	
	public abstract boolean isNullable();

	public abstract boolean isIndex();
	
	public abstract Index getIndex();

	@Override
	public String getColumnDefinition() {;
		return columnDefinition;
	}
	@Override
	public String getIndexDefinition() {
		return indexDefinition;
	}
	@Override
	public String getForeignKeyDefinition() {
		return foreignKeyDefinition;
	}

}
